#include "../mqserver/route.hpp"

#include <gtest/gtest.h>

class RouteTest: public testing::Environment
{
    virtual void SetUp() override
    {
    }
    virtual void TearDown() override
    {
        std::cout << "完成资源的清理化工作" << std::endl;
    }
};

TEST(route_test, legal_routing_key)
{
    ASSERT_EQ(mymq::Router::IsLegalRoutingKey("news.music.pop"), true);
    ASSERT_EQ(mymq::Router::IsLegalRoutingKey("news..music.pop"), true);
    ASSERT_EQ(mymq::Router::IsLegalRoutingKey("news.,music.pop"), false);
    ASSERT_EQ(mymq::Router::IsLegalRoutingKey("news.music_123.pop"), true);
}

TEST(route_test, legal_binding_key)
{
    ASSERT_EQ(mymq::Router::IsLegalBindingKey("news.music.pop"), true);
    ASSERT_EQ(mymq::Router::IsLegalBindingKey("news.#.music.pop"), true);
    ASSERT_EQ(mymq::Router::IsLegalBindingKey("news.#.*.music.pop"), false);
    ASSERT_EQ(mymq::Router::IsLegalBindingKey("news.*.#.music.pop"), false);
    ASSERT_EQ(mymq::Router::IsLegalBindingKey("news.#.#.music.pop"), false);
    ASSERT_EQ(mymq::Router::IsLegalBindingKey("news.*.*.music.pop"), true);
    ASSERT_EQ(mymq::Router::IsLegalRoutingKey("news.,music_123.pop"), false);
}

TEST(route_test, route_key)
{
    // binding key          routing key            result
    // aaa                  aaa                     true
    // aaa.bbb              aaa.bbb                 true
    // aaa.bbb              aaa.bbb.ccc             false
    // aaa.bbb              aaa.ccc                 false
    // aaa.#.bbb            aaa.bbb.ccc             false
    // aaa.bbb.#            aaa.ccc.bbb             false
    // #.bbb.ccc            aaa.bbb.ccc.ddd         false
    // aaa.bbb.ccc          aaa.bbb.ccc             true
    // aaa.*                aaa.bbb                 true
    // aaa.*.bbb            aaa.bbb.ccc             false
    // *.aaa.bbb            aaa.bbb                 false
    // #                    aaa.bbb.ccc             true
    // aaa.#                aaa.bbb                 true
    // aaa.#                aaa.bbb.ccc             true
    // aaa.#.ccc            aaa.ccc                 true
    // aaa.#.ccc            aaa.bbb.ccc             true
    // aaa.#.ccc            aaa.aaa.bbb.ccc         true
    // #.ccc                ccc                     true
    // #.ccc                aaa.bbb.ccc             true
    // aaa.#.ccc.ccc        aaa.bbb.ccc.ccc.ccc     true
    // aaa.#.bbb.*.bbb      aaa.ddd.ccc.bbb.eee.bbb true
    std::vector<std::string> bkeys = {
        "aaa",
        "aaa.bbb",
        "aaa.bbb",
        "aaa.bbb",
        "aaa.#.bbb",
        "aaa.bbb.#",
        "#.bbb.ccc",
        "aaa.bbb.ccc",
        "aaa.*",
        "aaa.*.bbb",
        "*.aaa.bbb",
        "#",
        "aaa.#",
        "aaa.#",
        "aaa.#.ccc",
        "aaa.#.ccc",
        "aaa.#.ccc",
        "#.ccc",
        "#.ccc",
        "aaa.#.ccc.ccc",
        "aaa.#.bbb.*.bbb"
    };
    std::vector<std::string> rkeys = {
        "aaa",
        "aaa.bbb",
        "aaa.bbb.ccc",
        "aaa.ccc",
        "aaa.bbb.ccc",
        "aaa.ccc.bbb",
        "aaa.bbb.ccc.ddd",
        "aaa.bbb.ccc",
        "aaa.bbb",
        "aaa.bbb.ccc",
        "aaa.bbb",   
        "aaa.bbb.ccc",
        "aaa.bbb",
        "aaa.bbb.ccc",
        "aaa.ccc",
        "aaa.bbb.ccc",
        "aaa.aaa.bbb.ccc",
        "ccc",
        "aaa.bbb.ccc",
        "aaa.bbb.ccc.ccc.ccc",
        "aaa.ddd.ccc.bbb.eee.bbb"
    };

    std::vector<bool> result = {
        true,
        true,
        false,
        false,
        false,
        false,
        false,
        true,
        true,
        false,
        false,
        true,
        true,
        true,
        true,
        true,
        true,
        true,
        true,
        true,
        true
    };

    for (int i = 0; i < bkeys.size(); i++)
    {
        ASSERT_EQ(mymq::Router::Route(mymq::ExchangeType::TOPIC, bkeys[i], rkeys[i]), result[i]);
    }
}

int main(int argc, char* argv[])
{
    testing::InitGoogleTest(&argc, argv);
    testing::AddGlobalTestEnvironment(new RouteTest);
    RUN_ALL_TESTS();

    return 0;
}